// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

/*
 * @Author: qiulin 1746365080@qq.com
 * @Date: 2024-10-24 14:51:52
 * @LastEditors: qiulin_JXGM ql1746365080@gmail.com
 * @LastEditTime: 2024-12-06 19:59:58
 * @FilePath: /SGSim/DBManager/UnitTest/HDF5/Input/MaterialServiceTest.cpp
 */

#include <gtest/gtest.h>

#include "DBManager/DBServiceFactory.h"
#include "DBManager/IService/Input/Material/IAnisotropic2DMaterialService.h"
#include "DBManager/IService/Input/Material/IAnisotropic3DMaterialService.h"
#include "DBManager/IService/Input/Material/IIsotropicMaterialService.h"
#include "DBManager/IService/Input/Material/IMaterialSummaryService.h"
#include "DBManager/IService/Input/Material/IOrthotropic2DMaterialService.h"
#include "DBManager/IService/Input/Material/IThermalMaterialService.h"
#include "DBManager/UnitTest/HDF5/TestDB.h"
using namespace SG::DataStructure::FEM;
using namespace SG::DBManager;

class I_MaterialTest : public testing::Test
{
  public:
    static void SetUpTestSuite ()
    {
        if (DB::ServiceFactory != nullptr)
        {
            DB::ServiceFactory->ClearDatabase ();
        }
    }
};

TEST_F (I_MaterialTest, IsotropicMaterialTest)
{
    IsotropicMaterial x;
    x.m_id        = 1;
    auto service  = DB::ServiceFactory->get<IIsotropicMaterialService> ();
    auto service2 = DB::ServiceFactory->get<IIsotropicMaterialService> ();

    service->Add (x);
    service2->Add (x);
    ASSERT_EQ (service->Size (), 2);
}

TEST_F (I_MaterialTest, Orthotropic2DMaterialTest)
{
    Orthotropic2DMaterial x;
    x.m_id       = 8;
    auto service = DB::ServiceFactory->get<IOrthotropic2DMaterialService> ();
    service->Add (x);
    x.m_id = 3;
    service->Add (x);
    ASSERT_EQ (service->Size (), 2);
}

TEST_F (I_MaterialTest, Anisotropic2DMaterialTest)
{
    Anisotropic2DMaterial x;
    x.m_id       = 2;
    auto service = DB::ServiceFactory->get<IAnisotropic2DMaterialService> ();
    service->Add (x);

    ASSERT_EQ (service->Size (), 1);
}

TEST_F (I_MaterialTest, Anisotropic3DMaterialTest)
{
    Anisotropic3DMaterial x;
    x.m_id       = 9;
    auto service = DB::ServiceFactory->get<IAnisotropic3DMaterialService> ();
    service->Add (x);

    ASSERT_EQ (service->Size (), 1);
}

TEST_F (I_MaterialTest, ThermalMaterialTest)
{
    ThermalMaterial x;
    x.m_id       = 4;
    auto service = DB::ServiceFactory->get<IThermalMaterialService> ();

    service->Add (x);
    ASSERT_EQ (service->Size (), 1);
}

TEST_F (I_MaterialTest, I_MaterialTest)
{
    auto service = DB::ServiceFactory->get<IMaterialSummaryService> ();

    ASSERT_EQ (service->GetMaterialType (1)[0], SG::DataStructure::FEM::MaterialTypes::MATTYPE_Isotropic);
    ASSERT_EQ (service->GetMaterialType (8)[0], SG::DataStructure::FEM::MaterialTypes::MATTYPE_2DOrthotropic);
    ASSERT_EQ (service->GetMaterialType (2)[0], SG::DataStructure::FEM::MaterialTypes::MATTYPE_2DAnisotropic);
    ASSERT_EQ (service->GetMaterialType (9)[0], SG::DataStructure::FEM::MaterialTypes::MATTYPE_3DAnisotropic);
    ASSERT_EQ (service->GetMaterialType (4)[0], SG::DataStructure::FEM::MaterialTypes::MATTYPE_THERMAL);
}

#include "DBManager/IService/Input/Material/IMAT1FService.h"
TEST_F (I_MaterialTest, MAT1FTest)
{
    DB::ServiceFactory->ClearDatabase ();

    auto service = DB::ServiceFactory->get<IMAT1FService> ();

    SG::DataStructure::FEM::MAT1FData data;
    data.m_id = 1;
    service->Add (data);

    SG::DataStructure::FEM::MAT1FData _OUT outData;
    service->FindById (1, outData);
    ASSERT_EQ (outData.m_id, 1);

    ASSERT_EQ (service->FindByIndex (0, outData), SG::DataStructure::Common::Status::STATUS_Success);

    ASSERT_EQ (outData.m_id, 1);

    ASSERT_EQ (service->Size (), 1);
    ASSERT_EQ (service->Count (1), 1);
}

#include "DBManager/IService/Input/Material/IMAT2FService.h"
TEST_F (I_MaterialTest, MAT2FTest)
{
    DB::ServiceFactory->ClearDatabase ();

    auto service = DB::ServiceFactory->get<IMAT2FService> ();

    SG::DataStructure::FEM::MAT2FData data;
    data.m_id = 1;
    service->Add (data);

    SG::DataStructure::FEM::MAT2FData _OUT outData;
    service->FindById (1, outData);
    ASSERT_EQ (outData.m_id, 1);

    ASSERT_EQ (service->FindByIndex (0, outData), SG::DataStructure::Common::Status::STATUS_Success);

    ASSERT_EQ (outData.m_id, 1);

    ASSERT_EQ (service->Size (), 1);
    ASSERT_EQ (service->Count (1), 1);
}

#include "DBManager/IService/Input/Material/IMAT8FService.h"
TEST_F (I_MaterialTest, MAT8FTest)
{
    DB::ServiceFactory->ClearDatabase ();

    auto service = DB::ServiceFactory->get<IMAT8FService> ();

    SG::DataStructure::FEM::MAT8FData data;
    data.m_id = 1;
    service->Add (data);

    SG::DataStructure::FEM::MAT8FData _OUT outData;
    service->FindById (1, outData);
    ASSERT_EQ (outData.m_id, 1);

    ASSERT_EQ (service->FindByIndex (0, outData), SG::DataStructure::Common::Status::STATUS_Success);

    ASSERT_EQ (outData.m_id, 1);

    ASSERT_EQ (service->Size (), 1);
    ASSERT_EQ (service->Count (1), 1);
}

#include "DBManager/IService/Input/Material/IMAT9FService.h"
TEST_F (I_MaterialTest, MAT9FTest)
{
    DB::ServiceFactory->ClearDatabase ();

    auto service = DB::ServiceFactory->get<IMAT9FService> ();

    SG::DataStructure::FEM::MAT9FData data;
    data.m_id = 1;
    ASSERT_EQ (service->Add (data), SG::DataStructure::Common::Status::STATUS_Success);

    SG::DataStructure::FEM::MAT9FData _OUT outData;
    ASSERT_EQ (service->FindById (1, outData), SG::DataStructure::Common::Status::STATUS_Success);
    ASSERT_EQ (outData.m_id, 1);

    ASSERT_EQ (service->FindByIndex (0, outData), SG::DataStructure::Common::Status::STATUS_Success);
    ASSERT_EQ (outData.m_id, 1);

    ASSERT_EQ (service->Size (), 1);
    ASSERT_EQ (service->Count (1), 1);
}
